home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-19
/
intrlib1.zip
/
TEXTWNDW.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-10
|
14KB
|
360 lines
/******************************************************************************
* Iteraction library - text windows. *
* *
* Written by Gershon Elber, Oct. 1990 *
*******************************************************************************
* Implements a text printf for graphics windows. *
*******************************************************************************
* History: *
* 29 Oct 90 - Version 1.0 by Gershon Elber. *
******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#ifdef __MSDOS__
#include <mem.h>
#endif /* __MSDOS__ */
#include "intr_loc.h"
#include "intr_gr.h"
static IntrBType SmoothScroll = FALSE;
static IntrBType WasAPrintf = FALSE;
static void ScrollAndPrint(_IntrWindowStruct *Window);
/******************************************************************************
* Select a window and initialize it to text drawing. *
******************************************************************************/
void IntrTextInitWindow(int WindowID,
IntrBType ReadBottomLine,
IntrColorType TextColor,
IntrColorType BottomLineColor,
IntrScrlBarType HScrlBar,
IntrScrlBarType VScrlBar,
int NumOfLines,
int LineLen)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
if (Window -> WindowType == INTR_WNDW_TEXT) {
_IntrFree(Window -> TextInfo -> TextData); /* Delete old data. */
}
else
Window -> TextInfo = (_IntrWndwTextStruct *)
_IntrMalloc(sizeof(_IntrWndwTextStruct));
Window -> TextInfo -> TextData = (char *) _IntrMalloc(NumOfLines * ++LineLen);
Window -> TextInfo -> ReadBottomLine = ReadBottomLine;
Window -> TextInfo -> TextColor = TextColor;
Window -> TextInfo -> BottomLineColor = BottomLineColor;
Window -> TextInfo -> NumOfLines = NumOfLines;
Window -> TextInfo -> LineLen = LineLen;
Window -> TextInfo -> LinesInBuffer = 0;
Window -> TextInfo -> FirstDisplayed = 0;
Window -> HScrlBar = HScrlBar;
Window -> VScrlBar = VScrlBar;
Window -> HScrlBarColor = Window -> VScrlBarColor = TextColor;
Window -> WindowType = INTR_WNDW_TEXT;
}
/******************************************************************************
* Free TextInfo structure. *
******************************************************************************/
void _IntrTextWndwDelete(_IntrWndwTextStruct *TextInfo)
{
_IntrFree(TextInfo -> TextData);
_IntrFree(TextInfo);
}
/******************************************************************************
* Set smooth scrolling for text windows. *
******************************************************************************/
void IntrTextSetSmoothScroll(IntrBType SmoothScrolling)
{
SmoothScroll = SmoothScrolling;
}
/******************************************************************************
* Draw all text defined for this window. *
* It is assumed the window is all visible and cleared. *
******************************************************************************/
void IntrTextWndwRefresh(int WindowID)
{
IntrRType RelativePosition, DisplayedFraction;
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
int i, j, NumOfDisplayedLines, FirstLine,
LineLen = Window -> TextInfo -> LineLen,
LinesInBuffer = Window -> TextInfo -> LinesInBuffer;
char
*TextData = Window -> TextInfo -> TextData;
IntrBType
LocalWasAPrintf = WasAPrintf;
_IntrWndwTextStruct
*TextInfo = Window -> TextInfo;
WasAPrintf = FALSE;
GRPushViewPort();
GRPushTextSetting();
GRSetTextJustify(GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_TOP);
GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
NumOfDisplayedLines = (Window -> BBox.Ymax - Window -> BBox.Ymin -
(TEXT_BORDER << 1)) / TEXT_BASE_LINE - 2;
if (TextInfo -> ReadBottomLine) NumOfDisplayedLines--;
if (NumOfDisplayedLines < 0) NumOfDisplayedLines = 0;
_GRSetViewPort(Window -> BBox.Xmin + TEXT_BORDER,
Window -> BBox.Ymin + TEXT_BORDER,
Window -> BBox.Xmax - TEXT_BORDER,
Window -> BBox.Ymax - TEXT_BORDER);
IntrAllocColor(TextInfo -> TextColor, INTR_INTENSITY_VHIGH);
if (LinesInBuffer > NumOfDisplayedLines) {
DisplayedFraction = ((IntrRType) NumOfDisplayedLines) / LinesInBuffer;
if (LocalWasAPrintf) {
RelativePosition = 1.0 - DisplayedFraction;
for (i = 0; i <= NumOfDisplayedLines; i++)
GRSText(0, i * TEXT_BASE_LINE,
&TextData[LineLen * (NumOfDisplayedLines - i)]);
TextInfo -> FirstDisplayed = 0; /* Allow smooth scroll. */
}
else {
if (Window -> VScrlBar != INTR_SCRLBAR_NONE &&
_IntrAsyncLastEvent.AsyncEvent == ASYNC_EVNT_VSCRLBAR) {
RelativePosition = _IntrAsyncLastEvent.R;
if (RelativePosition > 1.0 - DisplayedFraction)
RelativePosition = 1.0 - DisplayedFraction;
}
else {
RelativePosition = 1.0 - DisplayedFraction;
}
j = ((int) ((1.0 - DisplayedFraction - RelativePosition) *
LinesInBuffer));
for (i = 0; i <= NumOfDisplayedLines; i++) {
if (NumOfDisplayedLines - i + j < TextInfo -> LinesInBuffer)
GRSText(0, i * TEXT_BASE_LINE,
&TextData[LineLen * (NumOfDisplayedLines - i + j)]);
}
TextInfo -> FirstDisplayed = j;
}
}
else {
RelativePosition = 0.0;
DisplayedFraction = 1.0;
FirstLine = NumOfDisplayedLines - LinesInBuffer;
for (i = 1; i <= LinesInBuffer; i++)
GRSText(0, (FirstLine + i) * TEXT_BASE_LINE,
&TextData[LineLen * (LinesInBuffer - i)]);
TextInfo -> FirstDisplayed = 0; /* Allow smooth scroll. */
}
switch (Window -> VScrlBar) {
case INTR_SCRLBAR_LEFT:
IntrWndwUpdateScrollBar(WindowID, TRUE,
RelativePosition, DisplayedFraction);
break;
case INTR_SCRLBAR_RIGHT:
IntrWndwUpdateScrollBar(WindowID, TRUE,
RelativePosition, DisplayedFraction);
break;
}
IntrPushKbdEvent(KEY_REFRESH);
GRPopTextSetting();
GRPopViewPort();
}
/******************************************************************************
* Scroll one line and print the new line on the bottom. *
******************************************************************************/
static void ScrollAndPrint(_IntrWindowStruct *Window)
{
int i, Xmax, Ymax;
IntrRType RelativePosition, DisplayedFraction;
VoidPtr LineBuffer;
_IntrWndwTextStruct
*TextInfo = Window -> TextInfo;
TextInfo -> NumOfDisplayedLines = (Window -> BBox.Ymax -
Window -> BBox.Ymin - (TEXT_BORDER << 1)) / TEXT_BASE_LINE - 2;
if (TextInfo -> ReadBottomLine)
TextInfo -> NumOfDisplayedLines--;
if (TextInfo -> NumOfDisplayedLines < 0)
TextInfo -> NumOfDisplayedLines = 0;
if (IntrWndwIsAllVisible(Window -> WindowID)) {
GRPushViewPort();
_GRSetViewPort(0, 0, GRScreenMaxX, GRScreenMaxY);
GRPushTextSetting();
GRSetTextJustify(GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_TOP);
GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
if (SmoothScroll && TextInfo -> FirstDisplayed == 0) {
IntrAllocColor(TextInfo -> TextColor, INTR_INTENSITY_VHIGH);
#ifdef __MSDOS__
LineBuffer = _IntrMalloc(GRGetImageBufferSize(Window -> BBox.Xmin, 0,
Window -> BBox.Xmax, 0));
#endif /* __MSDOS__ */
_GRSetViewPort(Window -> BBox.Xmin + TEXT_BORDER,
Window -> BBox.Ymin + TEXT_BORDER,
Window -> BBox.Xmax - TEXT_BORDER,
Window -> BBox.Ymax - TEXT_BORDER);
/* Scroll full base line. */
Xmax = Window -> BBox.Xmax - Window -> BBox.Xmin - (TEXT_BORDER << 1);
Ymax = Window -> BBox.Ymax - Window -> BBox.Ymin - (TEXT_BORDER << 1);
for (i = TEXT_BASE_LINE; i <= Ymax; i++) {
#ifdef __MSDOS__
GRGetImageBuffer(0, i, Xmax, i, LineBuffer);
GRPutImageBuffer(0, i - TEXT_BASE_LINE, LineBuffer);
#endif /* __MSDOS__ */
#ifdef DJGCC
GRPutImageBuffer(0, i - TEXT_BASE_LINE,
GRGetImageBuffer(0, i, Xmax, i));
#endif /* DJGCC */
}
#ifdef __MSDOS__
_IntrFree(LineBuffer);
#endif /* __MSDOS__ */
/* Clear old bottom string and print new one. */
IntrAllocColor(Window -> BackColor, INTR_INTENSITY_HIGH);
GRSBar(0, TextInfo -> NumOfDisplayedLines * TEXT_BASE_LINE,
Xmax, TextInfo -> NumOfDisplayedLines * TEXT_BASE_LINE + 8);
IntrAllocColor(TextInfo -> TextColor, INTR_INTENSITY_VHIGH);
GRSText(0, TextInfo -> NumOfDisplayedLines * TEXT_BASE_LINE,
&TextInfo -> TextData[0]);
if (TextInfo -> LinesInBuffer > TextInfo -> NumOfDisplayedLines) {
RelativePosition =
1.0 - ((IntrRType) TextInfo -> NumOfDisplayedLines) /
TextInfo -> LinesInBuffer;
DisplayedFraction = 1.0 - RelativePosition;
}
else {
RelativePosition = 0.0;
DisplayedFraction = 1.0;
}
switch (Window -> VScrlBar) {
case INTR_SCRLBAR_LEFT:
IntrWndwUpdateScrollBar(Window -> WindowID, TRUE,
RelativePosition, DisplayedFraction);
break;
case INTR_SCRLBAR_RIGHT:
IntrWndwUpdateScrollBar(Window -> WindowID, TRUE,
RelativePosition, DisplayedFraction);
break;
}
}
else { /* No smooth scrolling. */
TextInfo -> FirstDisplayed = 0;
IntrAllocColor(Window -> BackColor, INTR_INTENSITY_HIGH);
GRSBar(Window -> BBox.Xmin, Window -> BBox.Ymin,
Window -> BBox.Xmax, Window -> BBox.Ymax);
WasAPrintf = TRUE;
IntrTextWndwRefresh(Window -> WindowID);
}
GRPopViewPort();
GRPopTextSetting();
}
else {
/* Need to pop up the window which probably will refresh all text. */
IntrWndwPop(Window -> WindowID, TRUE, FALSE);
}
}
/******************************************************************************
* Printf to the specified window. *
******************************************************************************/
void IntrPrintf(int WindowID, IntrBType UpdateWindow, char *CtrlStr, ...)
{
va_list ArgPtr;
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
_IntrWndwTextStruct
*TextInfo = Window -> TextInfo;
int i,j,
BufferSize = (Window -> TextInfo -> NumOfLines - 1) *
(Window -> TextInfo -> LineLen);
char Line[256], *p,
*TempBuffer = _IntrMalloc(BufferSize);
if (Window -> WindowType != INTR_WNDW_TEXT)
IntrFatalError("Window is not initialized to support text.");
/* Move all lines one place up. Since both source and destination share */
/* the same space we do it in two spaces. */
GEN_COPY(TempBuffer,
&Window -> TextInfo -> TextData[0],
BufferSize);
GEN_COPY(&Window -> TextInfo -> TextData[Window -> TextInfo -> LineLen],
TempBuffer,
BufferSize);
_IntrFree(TempBuffer);
va_start(ArgPtr, CtrlStr);
vsprintf(Line, CtrlStr, ArgPtr);
va_end(ArgPtr);
p = TextInfo -> TextData;
for (i = j = 0; i < TextInfo -> LineLen - 1 && Line[j]; j++) {
if (iscntrl(Line[j])) {
if (Line[j] == 9) { /* It is a tab. */
do p[i++] = ' ';
while (i < TextInfo -> LineLen && (i & 0x07) != 0);
}
}
else
p[i++] = Line[j];
}
p[i] = 0;
if (++TextInfo -> LinesInBuffer > TextInfo -> NumOfLines)
TextInfo -> LinesInBuffer = TextInfo -> NumOfLines;
if (UpdateWindow)
ScrollAndPrint(Window);
else
TextInfo -> FirstDisplayed = -1; /* Enforce full window refresh. */
}
/******************************************************************************
* Read a line input at a bottom of a given window into buffer. *
******************************************************************************/
void IntrGetLineWindow(int WindowID, char *Buffer, int BufferLen)
{
int GRLastColor = GRGetColor();
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
_IntrWndwTextStruct
*TextInfo = Window -> TextInfo;
int WindowLen = (Window -> BBox.Xmax - Window -> BBox.Xmin -
(TEXT_BORDER << 1)) / GRGetTextWidth("M");
GRPushViewPort();
_GRSetViewPort(Window -> BBox.Xmin, Window -> BBox.Ymin,
Window -> BBox.Xmax, Window -> BBox.Ymax);
GRGetGraphicLine(WindowID, TEXT_BORDER << 1,
Window -> BBox.Ymax - Window -> BBox.Ymin -
TEXT_BORDER - GRGetTextHeight("M"),
Buffer, BufferLen, WindowLen,
IntrAllocColor(TextInfo -> TextColor, INTR_INTENSITY_VHIGH),
IntrAllocColor(Window -> BackColor, INTR_INTENSITY_HIGH));
GRSetColor(GRLastColor);
GRPopViewPort();
}